/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
 */
package org.olap4j.mdx;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Utility methods for MDX parsing.
 * 
 * <p>
 * NOTE: Package protected. Not part of the public olap4j API.
 * 
 * @author jhyde
 * @since Jun 6, 2007
 */
class MdxUtil {
	private static final Pattern QUOT_PATTERN = Pattern.compile("\"", Pattern.LITERAL);

	/**
	 * Converts a string into a double-quoted string.
	 * 
	 * @param val
	 *            String
	 * @return String enclosed in double-quotes
	 */
	static String quoteForMdx(String val) {
		StringBuilder buf = new StringBuilder(val.length() + 20);
		buf.append("\"");
		buf.append(QUOT_PATTERN.matcher(val).replaceAll("\"\""));
		buf.append("\"");
		return buf.toString();
	}

	static String toString(ParseTreeNode node) {
		StringWriter sw = new StringWriter();
		ParseTreeWriter parseTreeWriter = new ParseTreeWriter(sw);
		node.unparse(parseTreeWriter);
		return sw.toString();
	}

	/**
	 * Encodes string for MDX (escapes ] as ]] inside a name).
	 * 
	 * @param st
	 *            String
	 * @return String escaped for inclusion in an MDX identifier
	 */
	static String mdxEncodeString(String st) {
		StringBuilder retString = new StringBuilder(st.length() + 20);
		for (int i = 0; i < st.length(); i++) {
			char c = st.charAt(i);
			if ((c == ']') && ((i + 1) < st.length()) && (st.charAt(i + 1) != '.')) {
				retString.append(']'); // escaping character
			}
			retString.append(c);
		}
		return retString.toString();
	}

	/**
	 * Creates a deep copy of a list.
	 * 
	 * @param list
	 *            List to be copied
	 * @return Copy of list, with each element deep copied
	 */
	@SuppressWarnings({ "unchecked" })
	static <E extends ParseTreeNode> List<E> deepCopyList(List<E> list) {
		// Don't make a copy of the system empty list. '==' is intentional.
		if (list == Collections.EMPTY_LIST) {
			return list;
		}
		final ArrayList<E> listCopy = new ArrayList<E>(list.size());
		for (E e : list) {
			listCopy.add((E) e.deepCopy());
		}
		return listCopy;
	}

	static void unparseList(ParseTreeWriter writer, List<ParseTreeNode> argList, String start, String mid, String end) {
		final PrintWriter pw = writer.getPrintWriter();
		pw.print(start);
		for (int i = 0; i < argList.size(); i++) {
			if (i > 0) {
				pw.print(mid);
			}
			argList.get(i).unparse(writer);
		}
		pw.print(end);
	}
}

// End MdxUtil.java
